package UI;

import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.BevelBorder;
import javax.swing.table.TableColumn;

import Logic.SQLReader;
import UI.BaseModels.BCBSPanel;
import UI.BaseModels.HeaderLabel;
import UI.BaseModels.ReturnToMainMenuButton;
import UI.TableModels.TableModelTransactions;

import javax.swing.ScrollPaneConstants;

import threads.BaseRunnableBCBS;

// TODO: Auto-generated Javadoc
/**
 * The Class TransactionsPanel.
 */
public class TransactionsPanel extends BCBSPanel {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -5929953497856118999L;
	
	/** The transaction table. */
	private JTable transactionTable;
	
	/** The btn refresh. */
	private JButton btnRefresh;
	
	/** The load more button. */
	private JButton loadMoreButton;
	
	/** The lbl transaction id. */
	private JLabel lblTransactionId;
	
	/** The txtpn text from transaction. */
	private JTextPane txtpnTextFromTransaction;
	
	/** The got transactions until. */
	private int gotTransactionsUntil;

	/** The scrollpane. */
	private JScrollPane scrollpane;
	
	/** The tablemodel. */
	private TableModelTransactions tablemodel;

	/**
	 * Instantiates a new transactions panel.
	 */
	public TransactionsPanel() {

		gotTransactionsUntil = 2147483647; // Initially get transactions with ID
											// below maximum int size. Then load
											// more until no lower IDs can be
											// found in SQL.

		ReturnToMainMenuButton rtmm = new ReturnToMainMenuButton();
		this.add(rtmm);

		HeaderLabel header = new HeaderLabel("Transactions");
		this.add(header);

		transactionTable = new JTable();
		transactionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		transactionTable.setRowSelectionAllowed(true);
		transactionTable.setBorder(new BevelBorder(BevelBorder.LOWERED, null,
				null, null, null));
		tablemodel = new TableModelTransactions();
		transactionTable.setModel(tablemodel);

		transactionTable.setBounds(0, 51, 305, 230);
		transactionTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
		transactionTable.setTableHeader(null);
		transactionTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				int row = transactionTable.getSelectedRow();
				if (row != -1) {
					selectTransaction(row);
				}
			}
		});

		TableColumn col1 = transactionTable.getColumnModel().getColumn(0);
		TableColumn col2 = transactionTable.getColumnModel().getColumn(1);
		TableColumn col3 = transactionTable.getColumnModel().getColumn(2);

		col1.setPreferredWidth(165);
		col2.setPreferredWidth(55);
		col3.setPreferredWidth(90);

		scrollpane = new JScrollPane(transactionTable);
		scrollpane.setViewportBorder(null);
		scrollpane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

		scrollpane.setBounds(0, 51, 305, 230);
		scrollpane.setVisible(true);
		this.add(scrollpane);

		JLabel lblUser = new JLabel("User");
		lblUser.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblUser.setBounds(61, 32, 26, 14);
		this.add(lblUser);

		JLabel lblAmount = new JLabel("Amount");
		lblAmount.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblAmount.setBounds(153, 32, 45, 14);
		this.add(lblAmount);

		JLabel lblDate = new JLabel("Date");
		lblDate.setFont(new Font("Tahoma", Font.BOLD, 11));
		lblDate.setBounds(235, 32, 27, 14);
		this.add(lblDate);

		btnRefresh = new JButton("Refresh");
		btnRefresh.addActionListener(new RefreshTransactions());
		btnRefresh.setBounds(189, 408, 110, 25);
		this.add(btnRefresh);

		feedbackLabel.setLocation(0, 150);

		lblTransactionId = new JLabel("No transactions");
		lblTransactionId.setFont(new Font("Tahoma", Font.PLAIN, 15));

		lblTransactionId.setBounds(5, 292, 170, 19);
		this.add(lblTransactionId);

		txtpnTextFromTransaction = new JTextPane();
		txtpnTextFromTransaction.setFont(new Font("Tahoma", Font.PLAIN, 12));
		txtpnTextFromTransaction.setBackground(SystemColor.control);
		txtpnTextFromTransaction.setText("");
		txtpnTextFromTransaction.setEditable(false);
		txtpnTextFromTransaction.setBounds(5, 322, 294, 75);
		this.add(txtpnTextFromTransaction);

		loadMoreButton = new JButton("Load more");
		loadMoreButton.setBounds(189, 291, 110, 25);
		loadMoreButton.addActionListener(new LoadMoreTransactions());
		loadMoreButton.setEnabled(false);
		add(loadMoreButton);
	}


	private class RefreshTransactions implements ActionListener {
		
		public void actionPerformed(ActionEvent arg0) {
			refreshTransactions();
		}
	}

	private class LoadMoreTransactions implements ActionListener {
		
		public void actionPerformed(ActionEvent arg0) {
			loadMoreTransactions();
		}
	}

	/**
	 * Scrolls the transactionTable to the top.
	 */
	public void scrollToTop() {
		scrollpane.getVerticalScrollBar().setValue(0);
		transactionTable.setRowSelectionInterval(0, 0);
	}

	/**
	 * Enables or disables the LoadMore-button based on argument specified.
	 *
	 * @param value
	 * If true enables to button, if false disables it.
	 */
	public void enableLoadMoreButton(boolean value) {
		if (value) {
			loadMoreButton.setEnabled(true);
		} else {
			loadMoreButton.setEnabled(false);
		}

	}

	/**
	  * Enables or disables the Refresh-button based on argument specified.
	 *
	 * @param value
	 * If true enables to button, if false disables it.
	 */
	public void enableRefreshButton(boolean value) {
		if (value) {
			btnRefresh.setEnabled(true);
		} else {
			btnRefresh.setEnabled(false);
		}
	}

	/**
	 * Sets the label containing the Transaction ID to whatever argument is specified.
	 *
	 * @param id
	* The ID to append to the text.
	 */
	public void setTransactionID(String id) {
		lblTransactionId.setText("Transaction #" + id);
	}

	/**
	 * Sets the transaction text to whatever argument is specified. This could be the message attached to the transaction and date.
	 *
	 * @param text
	 * The text to set in the transaction text field.
	 */
	public void setTransactionText(String text) {
		txtpnTextFromTransaction.setText(text);
	}

	/**
	 * Clears all feedback fields, resets buttons and the gotTransactionsUntil variable. Overries superclass method.
	 */
	@Override
	public void clearFields() {
		feedbackLabel.setText("");
		lblTransactionId.setText("No transactions");
		txtpnTextFromTransaction.setText("");
		loadMoreButton.setEnabled(true);
		btnRefresh.setEnabled(true);
		gotTransactionsUntil = 2147483647;
		tablemodel.clearTable();
	}

	/**
	 * Creates a new Runnable of the type loadMoreTransactions, sets it to the
	 * current runnable for the panel, places it in its own thread and runs it.
	 */
	public void loadMoreTransactions() {
		runnable = new LoadMoreTransactionsRunnable();
		Thread t = new Thread(runnable);
		t.start();
	}

	/**
	 * Creates a new Runnable of the type RefreshUsersRunnable, sets it to the
	 * current runnable for the panel, places it in its own thread and runs it.
	 */
	public void refreshTransactions() {
		runnable = new RefreshTransactionsRunnable();
		Thread t = new Thread(runnable);
		t.start();
	}

	/**
	 * Selects the row of the JTable passed as argument (int) and sets the text and ID fields for the panel according to results fetched.
	 *
	 * @param row
	 * The row to fetch.
	 */
	public void selectTransaction(int row) {
		if (tablemodel.getRowCount() > 0) {
			Object objid = tablemodel.getValueAt(row, 5);
			Object objmessage = tablemodel.getValueAt(row, 4);
			Object objlongdate = tablemodel.getValueAt(row, 6);
			setTransactionID(objid.toString());
			setTransactionText(objmessage.toString() + "\nDate: "
					+ objlongdate.toString());
		}
	}

	/**
	 * The Class LoadMoreTransactionsRunnable.
	 */
	private class LoadMoreTransactionsRunnable extends BaseRunnableBCBS {
		
		/**
		 * Denne metode overskriver den indbyggede run-metode i klassen 
		 * BaseRunnableBCBS. Metoden henter transaction fra vores SQL-database 
		 * hvor transaktionerne har et lavere ID end variablen gotTransactionsUntil.
		 */

		@Override
		public void run() {
			SQLReader reader = new SQLReader();
			enableRefreshButton(false);
			enableLoadMoreButton(false);
			feedback("Loading...", true);
			try {
				if (!stop) {
					int lowestid = tablemodel.addData(reader.getTransactions(
							UI.MainFrame.currentUser.getId(),
							gotTransactionsUntil));
					if (!stop) {
						gotTransactionsUntil = lowestid;
					}
				}
				if (!stop) {
					if (gotTransactionsUntil == -1) {
						enableLoadMoreButton(false);
					} else {
						enableLoadMoreButton(true);
					}
					enableRefreshButton(true);
					clearFeedback();
					selectTransaction(0);
				}
			} catch (SQLException e) {
				if (!stop) {
					feedback("Connection Error! Try again!", false);
					enableRefreshButton(true);
				}

			}
		}
	}

	/**
	 * The Class RefreshTransactionsRunnable.
	 */
	private class RefreshTransactionsRunnable extends BaseRunnableBCBS {

		/* (non-Javadoc)
		 * @see threads.BaseRunnableBCBS#run()
		 */
		@Override
		public void run() {
			SQLReader reader = new SQLReader();
			feedback("Loading....", true);
			enableRefreshButton(false);
			enableLoadMoreButton(false);
			try {
				if (!stop) {
					int lowestid = tablemodel.refreshData(reader
							.getTransactions(UI.MainFrame.currentUser.getId(),
									2147483647));
					if (!stop) {
						gotTransactionsUntil = lowestid;
					} 
				}

				if (!stop) {
					if (gotTransactionsUntil == -1) {
						enableLoadMoreButton(false);
					} else {
						enableLoadMoreButton(true);

					}
					scrollToTop();
					selectTransaction(0);
					enableRefreshButton(true);
					clearFeedback();
				}
			} catch (SQLException e) {
				if (!stop) {
					feedback("Connection Error! Try again!", false);
					enableRefreshButton(true);
				}
			}
		}
	}

}
